/*
-----------------------------------------------------------------------------
This source file is part of Labor3D
(Labor 3D Graphics Engine)

Copyright (c) 2009-2020 Rock Mao
* creator : Rock Mao
* created : 2010-5-28   21:45
* filename: LFilePack.h

-----------------------------------------------------------------------------
*/

#ifndef __LFILEPACK_H__
#define __LFILEPACK_H__

#include "LFilePackImp.h"


class CLDirFPBuilder;

class CLFilePack
{
	vector<sFPDataEntry>     m_listDataEntry;
	wchar_t                  m_file_name[FILENAMELENGTH];
	sFPFileHeader            m_FileHeader;
	LOpenMode                m_eMode;
	sFPHashTableItem*        m_pHashTable;
	wstring                  m_BaseDir;

	friend class CLDirFPBuilder;
public:
	CLFilePack();
	~CLFilePack();

	bool open(const wchar_t* file_name, LOpenMode eOpenMode, bool bCreate = false );
	bool save();
	bool addFile( const wchar_t* file_name);
	
	bool unwrapBuffer( const wchar_t* name, char** ppBuffer );
	bool unwrapFile( const wchar_t* name, const wchar_t* file_name );
	bool pack_dir(const wchar_t* dir);
	bool unpack(const wchar_t* obj_dir );
protected:
	bool create(const wchar_t* file_name,int hash_table_size=256);
	bool _fill_header();
	bool _write_data_to_stream(ostream& stream);
	bool _unpack_data(ifstream & stream, const wchar_t* file_name, sFPDataEntryInfo& entryInfo );

	bool _write_data_to_file(char* pData, const wchar_t* file_name, int nLength );

	/// hashtable
	void __init_hash_table(int hash_table_size);
	void __clear_hash_table();
	void __resize_hash_table(int hash_table_size);
	void __recalculate_hash_table();
	void __fit_hash_table();

	/// file operator
	bool __insert_data( const wchar_t* name, const wchar_t* full_name = NULL, lfp_data_type type = lfpdt_file, int compress_rate = 100 );
	bool __insert_file( const wchar_t* name,const wchar_t* full_name , lfp_data_type type = lfpdt_file, int compress_rate = 100 );
	bool __insert_buffer( const wchar_t* name, int compress_rate = 100 );
    //// 
	long __calDataEntryPoint();

	/// read
	bool __open_for_read(const wchar_t* file_name);
	bool __open_for_read(ifstream & stream);

};
#endif